package com.sumainfor.common.wechat;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

public class RequestUtil {
	    //控制台打印信息
		protected static Logger logger = LoggerFactory.getLogger(RequestUtil.class);
		/**
		 * 组装请求数据字符串
		 * @author
		 * @param "xml" 根元素名称
		 * @param postData 请求数据
		 * @return
		 */
		public static String toXml(TreeMap<String, String> postData){
			Element root = DocumentHelper.createElement("xml");
			Document document = DocumentHelper.createDocument(root);
			List<String> keys = new ArrayList<String>(postData.keySet());
			// 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）  
			Collections.sort(keys);
			//把签名放到最后
			String sign =null;
			for(int j=0;j<keys.size();j++){
				if(keys.get(j).equals("sign")){
					sign = keys.get(j);
					keys.remove(j);
				}
			}
			keys.add(sign);
			for (int i = 0; i < keys.size(); i++){
			
				String key = keys.get(i);
				String value = postData.get(key);
				Element element = root.addElement(key);
				element.addText(StringUtils.isEmpty(value) ? "" : value);
			}

			return document.asXML();
	}
		
		/**
		 * 提交http请求，获取响应数据字符串
		 * 
		 * @param url 请求URL
		 *            
		 * @headerInfo 请求头信息
		 * @param xml 请求数据字符串
		 *            
		 * @return
		 * @throws ClientProtocolException
		 * @throws IOException
		 * @author 
		 *         
		 */
		public static String postXml(String url, String xml) throws Exception
		{
			String result = null;
			HttpEntity postEntity = new StringEntity(xml, "utf-8");
			HttpPost httpPost = new HttpPost(url);

			Map<String, String> headerInfo = new HashMap<String, String>();
			headerInfo.put("Content-Type", "text/xml");
			headerInfo.put("Connection", "keep-alive");
			headerInfo.put("Accept", "*/*");
			headerInfo.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
			headerInfo.put("Host", "api.mch.weixin.qq.com");
			headerInfo.put("X-Requested-With", "XMLHttpRequest");
			headerInfo.put("Cache-Control", "max-age=0");
			headerInfo.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");

			if (headerInfo != null)
			{
				Iterator<String> it = headerInfo.keySet().iterator();
				while (it.hasNext())
				{
					String name = it.next();
					String value = headerInfo.get(name);
					httpPost.addHeader(name, value);
				}
			}
			httpPost.setEntity(postEntity);

			CloseableHttpClient httpclient = HttpClients.custom().build();
			try
			{
				HttpResponse response = httpclient.execute(httpPost);
				int statusCode = response.getStatusLine().getStatusCode();
				if (statusCode == HttpStatus.SC_OK)
				{
					HttpEntity entity = response.getEntity();
					if (entity != null)
					{
						result = EntityUtils.toString(entity, "utf-8");
					}
				}
			}
			catch (Exception e)
			{
				logger.error(e.getMessage());
			}
			finally
			{
				httpclient.close();
			}
			return result;
		}
		
		/**
		 * org.dom4j.Document 转  com.alibaba.fastjson.JSONObject
		 * @param xml
		 * @return
		 * @throws DocumentException
		 */
		public static JSONObject documentToJSONObject(String xml) throws DocumentException {
			return elementToJSONObject(DocumentHelper.parseText(xml).getRootElement());
		}
		
		/**
		 * org.dom4j.Element 转  com.alibaba.fastjson.JSONObject
		 * @param node
		 * @return
		 */
		public static JSONObject elementToJSONObject(Element node) {
			JSONObject result = new JSONObject();
			// 当前节点的名称、文本内容和属性
			List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
			for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
				result.put(attr.getName(), attr.getValue());
			}
			// 递归遍历当前节点所有的子节点
			List<Element> listElement = node.elements();// 所有一级子节点的list
			if (!listElement.isEmpty()) {
				for (Element e : listElement) {// 遍历所有一级子节点
					if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点
						result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待
					else {
						if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性
							result.put(e.getName(), new JSONArray());// 没有则创建
						((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中
					}
				}
			}
			return result;
		}

}
